package com.socialsoftware.MediaCommunication.view;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.widget.RelativeLayout;

import com.socialsoftware.R;

import java.util.ArrayList;
import java.util.List;

/**
 * A custom view that creates ripple animation effect around a center view
 */
public class RippleAnimationView extends RelativeLayout {
    private static final int DEFAULT_RIPPLE_COUNT = 3;
    private static final int DEFAULT_DURATION = 3000;
    private static final float DEFAULT_SCALE = 6.0f;
    private static final int DEFAULT_RIPPLE_COLOR = 0x30ffffff;
    private static final int DEFAULT_STROKE_WIDTH = 2;

    private int rippleColor;
    private float rippleStrokeWidth;
    private float rippleRadius;
    private int rippleCount;
    private int rippleDuration;
    private float rippleScale;
    private boolean isRunning = false;
    
    private Paint paint;
    private AnimatorSet animatorSet;
    private List<Ripple> ripples = new ArrayList<>();
    private int width = 0;
    private int height = 0;

    public RippleAnimationView(Context context) {
        super(context);
        init(context, null);
    }

    public RippleAnimationView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public RippleAnimationView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        // Default values
        rippleColor = DEFAULT_RIPPLE_COLOR;
        rippleStrokeWidth = DEFAULT_STROKE_WIDTH;
        rippleCount = DEFAULT_RIPPLE_COUNT;
        rippleDuration = DEFAULT_DURATION;
        rippleScale = DEFAULT_SCALE;
        
        // Read attributes if available
        if (attrs != null) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RippleAnimationView);
            rippleColor = typedArray.getColor(R.styleable.RippleAnimationView_rippleColor, DEFAULT_RIPPLE_COLOR);
            rippleStrokeWidth = typedArray.getDimension(R.styleable.RippleAnimationView_rippleStrokeWidth, DEFAULT_STROKE_WIDTH);
            rippleRadius = typedArray.getDimension(R.styleable.RippleAnimationView_rippleRadius, 0);
            rippleCount = typedArray.getInt(R.styleable.RippleAnimationView_rippleCount, DEFAULT_RIPPLE_COUNT);
            rippleDuration = typedArray.getInt(R.styleable.RippleAnimationView_rippleDuration, DEFAULT_DURATION);
            rippleScale = typedArray.getFloat(R.styleable.RippleAnimationView_rippleScale, DEFAULT_SCALE);
            typedArray.recycle();
        }
        
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(rippleStrokeWidth);
        paint.setColor(rippleColor);
        
        // Set view properties
        setWillNotDraw(false);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
        
        // If ripple radius is not set, use the smaller dimension / 2
        if (rippleRadius == 0) {
            rippleRadius = Math.min(w, h) / 2f - rippleStrokeWidth;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        
        // Draw all ripples
        for (Ripple ripple : ripples) {
            if (ripple.alpha > 0) {
                paint.setAlpha(ripple.alpha);
                canvas.drawCircle(width / 2f, height / 2f, ripple.radius, paint);
            }
        }
    }

    /**
     * Start the ripple animation
     */
    public void startRippleAnimation() {
        if (isRunning) {
            return;
        }
        
        isRunning = true;
        createRipples();
        
        // Start animation
        if (animatorSet != null && animatorSet.isRunning()) {
            animatorSet.cancel();
        }
        
        animatorSet = new AnimatorSet();
        List<Animator> animators = new ArrayList<>();
        
        for (int i = 0; i < rippleCount; i++) {
            Ripple ripple = ripples.get(i);
            
            // Scale animation
            ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(ripple, "radius", rippleRadius, rippleRadius * rippleScale);
            scaleAnimator.setRepeatCount(Animation.INFINITE);
            scaleAnimator.setRepeatMode(Animation.RESTART);
            scaleAnimator.setStartDelay(i * rippleDuration / rippleCount);
            scaleAnimator.setDuration(rippleDuration);
            
            // Alpha animation
            ObjectAnimator alphaAnimator = ObjectAnimator.ofInt(ripple, "alpha", 255, 0);
            alphaAnimator.setRepeatCount(Animation.INFINITE);
            alphaAnimator.setRepeatMode(Animation.RESTART);
            alphaAnimator.setStartDelay(i * rippleDuration / rippleCount);
            alphaAnimator.setDuration(rippleDuration);
            
            animators.add(scaleAnimator);
            animators.add(alphaAnimator);
        }
        
        animatorSet.playTogether(animators);
        animatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
        animatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {}

            @Override
            public void onAnimationEnd(Animator animation) {
                isRunning = false;
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                isRunning = false;
            }

            @Override
            public void onAnimationRepeat(Animator animation) {}
        });
        animatorSet.start();
    }

    /**
     * Stop the ripple animation
     */
    public void stopRippleAnimation() {
        if (animatorSet != null && animatorSet.isRunning()) {
            animatorSet.cancel();
        }
        isRunning = false;
    }

    private void createRipples() {
        ripples.clear();
        for (int i = 0; i < rippleCount; i++) {
            ripples.add(new Ripple(rippleRadius, 255));
        }
    }

    /**
     * Class to represent a single ripple
     */
    private static class Ripple {
        private float radius;
        private int alpha;

        Ripple(float radius, int alpha) {
            this.radius = radius;
            this.alpha = alpha;
        }

        public float getRadius() {
            return radius;
        }

        public void setRadius(float radius) {
            this.radius = radius;
        }

        public int getAlpha() {
            return alpha;
        }

        public void setAlpha(int alpha) {
            this.alpha = alpha;
        }
    }
} 